#include <my_header.h>
#include "TLV.h"
#define MAX_INPUT_SIZE 1024
#define MAX_EPOLL_EVENTS_NUM 10
#define MAX_PARTS 10

// 切分输入为命令和参数
int split_input(char *input, char *delimiter, char *parts[]) {
    char *save_state_strtok_r;
    char *token = strtok_r(input, delimiter,&save_state_strtok_r);
    int count = 0;
    while (token != NULL) {
        parts[count++] = token;
        token = strtok_r(NULL, delimiter,&save_state_strtok_r);
    }
    return count;
}
// 判断输入是否合法
int is_input_valid(char *command, int count) {
    if (strcmp(command, "cd") == 0) {
        // cd 必须有两部分
        return count == 2;
    } else if (strcmp(command, "pwd") == 0) {
        // pwd 必须只有一部分
        return count == 1;
    } else if (strcmp(command, "ll") == 0) {
        // ll 可以是一部分或两部分
        return count == 1 || count == 2;
    } else if (strcmp(command, "ls") == 0){
        // ls 可以是一部分或两部分
        return count == 1 || count == 2;
    } else if (strcmp(command, "mkdir") == 0){
        // mkdir 必须有两部分
        return count == 2;
    } else if (strcmp(command, "rmdir") == 0){
        // rmdir 必须有两部分
        return count == 2;
    } else if (strcmp(command, "remove") == 0){
        // remove 必须有两部分
        return count == 2;
    } else if (strcmp(command, "puts") == 0){
        // puts 必须有两部分
        return count == 2;
    } else if (strcmp(command, "gets") == 0){
        // gets 必须有两部分
        return count == 2;
    } else {
        // 未知命令
        return 0;
    }
}

/* Usage:  */
int main(int argc, char *argv[]){                                  
    // ./client 192.168.72.128 12345
    ARGS_CHECK(argc,3);
    int sockfd = socket(AF_INET,SOL_SOCKET,0);//
    ERROR_CHECK(sockfd,-1,"socket");
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
    ERROR_CHECK(ret,-1,"connect");

    /* sendMSG(sockfd); */
    //处理用户输入
    //1.建立epoll，监听客户端stdin和服务端返回内容sockfd
    int epfd = epoll_create(1);
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = STDIN_FILENO;
    //stdin加入监听
    epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&event);
    event.events = EPOLLIN;
    event.data.fd = sockfd;
    //sockfd加入监听
    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);

    struct epoll_event readySet[10];

    char username[1024] = {0};
    printf("连接到服务器，请输入用户名\n");
    scanf("%s",username);

    send_username(sockfd,username);

    while(1){
        int readyNum = epoll_wait(epfd, readySet, MAX_EPOLL_EVENTS_NUM, -1);
        for(int i=0;i<readyNum;i++){
            if(readySet[i].data.fd == STDIN_FILENO){
                //用户有输入
                char input[4096] = {0};
                //切分完后又几个部分
                //存放切分后的部分
                char *parts[MAX_PARTS];
                //获取用户的输入,最后一个留给\0
                int read_count_from_stdin = read(STDIN_FILENO,input,sizeof(input));
                if(read_count_from_stdin == 0){
                    printf("客户端%s断开连接\n",username);
                    goto end;
                }
                input[strcspn(input, "\n")] = '\0'; // 去掉换行符
                /* printf("input = %s\n",input); */                                    

                // 切分输入
                int count = split_input(input," ",parts);
                // 用户没有输入，跳过本次循环
                if (count == 0) {
                    continue;
                }
                char *command = parts[0];
                if (is_input_valid(command, count)) {
                    //命令合法，发送给服务端

                    /* for(int i=0;i<count;i++){ */
                    /* printf("i=%d\tparts[i]=%s\n",i,parts[i]); */
                    /* } */

                    send_command(sockfd,parts,count);
                    if(strcmp(command,"puts")==0){
                        char* file_name = parts[1];
                        int retv = trans_file_to_server(sockfd,file_name);
                        if(retv == -1){
                            printf("你输入的文件名有问题\n");
                            continue;
                        }
                    }else if(strcmp(command,"gets")==0){
                        char* file_name = parts[1];
                        int retv = recv_file_from_server(sockfd,file_name);
                        if(retv == -1){
                            printf("没有此文件\n");
                            continue;
                        }
                    }              
                } else {
                    printf("请输入合法命令\n");
                }
            }else if(readySet[i].data.fd == sockfd){
                //服务端返回结果
                char result[4096];
                int recv_count_from_server = recv_result(sockfd,result);

                if(recv_count_from_server == 0){
                    printf("服务器停机，断开连接\n");
                    goto end;
                }

                printf("%s\n",result);
            }
        }
    }
end:
    close(sockfd);
    return 0;
}

